home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Metrowerks CodeWarrior / Java Support / Java_Source / Java2 / src / java / awt / Checkbox.java < prev    next >
Encoding:
Java Source  |  1999-05-28  |  15.0 KB  |  502 lines  |  [TEXT/CWIE]

  1. /*
  2.  * @(#)Checkbox.java    1.49 98/08/19
  3.  *
  4.  * Copyright 1995-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14. package java.awt;
  15.  
  16. import java.awt.peer.CheckboxPeer;
  17. import java.awt.event.*;
  18. import java.io.ObjectOutputStream;
  19. import java.io.ObjectInputStream;
  20. import java.io.IOException;
  21.  
  22.  
  23. /**
  24.  * A check box is a graphical component that can be in either an
  25.  * "on" (<code>true</code>) or "off" (<code>false</code>) state.
  26.  * Clicking on a check box changes its state from
  27.  * "on" to "off," or from "off" to "on."
  28.  * <p>
  29.  * The following code example creates a set of check boxes in
  30.  * a grid layout:
  31.  * <p>
  32.  * <hr><blockquote><pre>
  33.  * setLayout(new GridLayout(3, 1));
  34.  * add(new Checkbox("one", null, true));
  35.  * add(new Checkbox("two"));
  36.  * add(new Checkbox("three"));
  37.  * </pre></blockquote><hr>
  38.  * <p>
  39.  * This image depicts the check boxes and grid layout
  40.  * created by this code example:
  41.  * <p>
  42.  * <img src="doc-files/Checkbox-1.gif"
  43.  * ALIGN=center HSPACE=10 VSPACE=7>
  44.  * <p>
  45.  * The button labeled <code>one</code> is in the "on" state, and the
  46.  * other two are in the "off" state. In this example, which uses the
  47.  * <code>GridLayout</code> class, the states of the three check
  48.  * boxes are set independently.
  49.  * <p>
  50.  * Alternatively, several check boxes can be grouped together under
  51.  * the control of a single object, using the
  52.  * <code>CheckboxGroup</code> class.
  53.  * In a check box group, at most one button can be in the "on"
  54.  * state at any given time. Clicking on a check box to turn it on
  55.  * forces any other check box in the same group that is on
  56.  * into the "off" state.
  57.  *
  58.  * @version    1.49 08/19/98
  59.  * @author     Sami Shaio
  60.  * @see         java.awt.GridLayout
  61.  * @see         java.awt.CheckboxGroup
  62.  * @since       JDK1.0
  63.  */
  64. public class Checkbox extends Component implements ItemSelectable {
  65.  
  66.     static {
  67.         /* ensure that the necessary native libraries are loaded */
  68.     Toolkit.loadLibraries();
  69.         initIDs();
  70.     }
  71.  
  72.     /**
  73.      * The label of the Checkbox.
  74.      * This field can be null. If a label is not specified it 
  75.      * defaults to null or "".
  76.      * @serial
  77.      * @see getLabel()
  78.      * @see setLabel()
  79.      */
  80.     String label;
  81.  
  82.     /**
  83.      * The state of the Checkbox.
  84.      * @serial
  85.      * @see getState()
  86.      * @see setLabel()
  87.      */
  88.     boolean state;
  89.  
  90.     /**
  91.      * The check box group.
  92.      * This field can be null indicating that the checkbox
  93.      * is not a group checkbox.  
  94.      * @serial
  95.      * @see getCheckBoxGroup()
  96.      * @see setCheckBoxGroup()
  97.      */
  98.     CheckboxGroup group;
  99.  
  100.     transient ItemListener itemListener;
  101.  
  102.     private static final String base = "checkbox";
  103.     private static int nameCounter = 0;
  104.  
  105.     /*
  106.      * JDK 1.1 serialVersionUID
  107.      */
  108.     private static final long serialVersionUID = 7270714317450821763L;
  109.  
  110.     /**
  111.      * Helper function for setState and CheckboxGroup.setSelectedCheckbox
  112.      * Should remain package-private.
  113.      */
  114.     void setStateInternal(boolean state) {
  115.     this.state = state;
  116.     CheckboxPeer peer = (CheckboxPeer)this.peer;
  117.     if (peer != null) {
  118.         peer.setState(state);
  119.     }
  120.     }
  121.  
  122.     /**
  123.      * Creates a check box with no label. The state of this
  124.      * check box is set to "off," and it is not part of any
  125.      * check box group.
  126.      */
  127.     public Checkbox() {
  128.         this("", false, null);
  129.     }
  130.  
  131.     /**
  132.      * Creates a check box with the specified label.  The state
  133.      * of this check box is set to "off," and it is not part of
  134.      * any check box group.
  135.      * @param     label   a string label for this check box,
  136.      *                        or <code>null</code> for no label.
  137.      */
  138.     public Checkbox(String label) {
  139.     this(label, false, null);
  140.     }
  141.  
  142.     /**
  143.      * Creates a check box with the specified label
  144.      * and sets the specified state.
  145.      * This check box is not part of any check box group.
  146.      * @param     label   a string label for this check box,
  147.      *                        or <code>null</code> for no label.
  148.      * @param     state    the initial state of this check box.
  149.      */
  150.     public Checkbox(String label, boolean state) {
  151.         this(label, state, null);
  152.     }
  153.  
  154.     /**
  155.      * Creates a check box with the specified label, in the specified
  156.      * check box group, and set to the specified state.
  157.  
  158.      * @param     label   a string label for this check box,
  159.      *                        or <code>null</code> for no label.
  160.      * @param     state   the initial state of this check box.
  161.      * @param     group   a check box group for this check box,
  162.      *                           or <code>null</code> for no group.
  163.      * @since     JDK1.1
  164.      */
  165.     public Checkbox(String label, boolean state, CheckboxGroup group) {
  166.     this.label = label;
  167.     this.state = state;
  168.     this.group = group;
  169.     if (state && (group != null)) {
  170.         group.setSelectedCheckbox(this);
  171.     }
  172.     }
  173.  
  174.     /**
  175.      * Constructs a Checkbox with the specified label, set to the
  176.      * specified state, and in the specified check box group.
  177.      *
  178.      * @param     label   a string label for this check box,
  179.      *                        or <code>null</code> for no label.
  180.      * @param     group   a check box group for this check box,
  181.      *                           or <code>null</code> for no group.
  182.      * @param     state   the initial state of this check box.
  183.      * @since     JDK1.1
  184.      */
  185.     public Checkbox(String label, CheckboxGroup group, boolean state) {
  186.         this(label, state, group);
  187.     }
  188.  
  189.     /**
  190.      * Construct a name for this component.  Called by getName() when the
  191.      * name is null.
  192.      */
  193.     String constructComponentName() {
  194.         synchronized (getClass()) {
  195.         return base + nameCounter++;
  196.     }
  197.     }
  198.  
  199.     /**
  200.      * Creates the peer of the Checkbox. The peer allows you to change the
  201.      * look of the Checkbox without changing its functionality.
  202.      * @see     java.awt.Toolkit#createCheckbox(java.awt.Checkbox)
  203.      * @see     java.awt.Component#getToolkit()
  204.      */
  205.     public void addNotify() {
  206.         synchronized (getTreeLock()) {
  207.         if (peer == null) 
  208.             peer = getToolkit().createCheckbox(this);
  209.         super.addNotify();
  210.     }
  211.     }
  212.  
  213.     /**
  214.      * Gets the label of this check box.
  215.      * @return   the label of this check box, or <code>null</code>
  216.      *                  if this check box has no label.
  217.      * @see      java.awt.Checkbox#setLabel
  218.      */
  219.     public String getLabel() {
  220.     return label;
  221.     }
  222.  
  223.     /**
  224.      * Sets this check box's label to be the string argument.
  225.      * @param    label   a string to set as the new label, or
  226.      *                        <code>null</code> for no label.
  227.      * @see      java.awt.Checkbox#getLabel
  228.      */
  229.     public void setLabel(String label) {
  230.         boolean testvalid = false;
  231.  
  232.     synchronized (this) {
  233.         if (label != this.label && (this.label == null ||
  234.                     !this.label.equals(label))) {
  235.             this.label = label;
  236.         CheckboxPeer peer = (CheckboxPeer)this.peer;
  237.         if (peer != null) {
  238.             peer.setLabel(label);
  239.         }
  240.         testvalid = true;
  241.         }
  242.     }
  243.         
  244.     // This could change the preferred size of the Component.
  245.     if (testvalid && valid) {
  246.         invalidate();
  247.     }
  248.     }
  249.  
  250.     /**
  251.      * Determines whether this check box is in the "on" or "off" state.
  252.      * The boolean value <code>true</code> indicates the "on" state,
  253.      * and <code>false</code> indicates the "off" state.
  254.      * @return    the state of this check box, as a boolean value.
  255.      * @see       java.awt.Checkbox#setState
  256.      */
  257.     public boolean getState() {
  258.     return state;
  259.     }
  260.  
  261.     /**
  262.      * Sets the state of this check box to the specified state.
  263.      * The boolean value <code>true</code> indicates the "on" state,
  264.      * and <code>false</code> indicates the "off" state.
  265.      * @param     state   the boolean state of the check box.
  266.      * @see       java.awt.Checkbox#getState
  267.      */
  268.     public void setState(boolean state) {
  269.     /* Cannot hold check box lock when calling group.setSelectedCheckbox. */
  270.         CheckboxGroup group = this.group;
  271.     if (group != null) {
  272.         if (state) {
  273.         group.setSelectedCheckbox(this);
  274.         } else if (group.getSelectedCheckbox() == this) {
  275.         state = true;
  276.         }
  277.     }
  278.     setStateInternal(state);
  279.     }
  280.  
  281.     /**
  282.      * Returns an array (length 1) containing the checkbox
  283.      * label or null if the checkbox is not selected.
  284.      * @see ItemSelectable
  285.      */
  286.     public Object[] getSelectedObjects() {
  287.         if (state) {
  288.             Object[] items = new Object[1];
  289.             items[0] = label;
  290.             return items;
  291.         }
  292.         return null;
  293.     }
  294.  
  295.     /**
  296.      * Determines this check box's group.
  297.      * @return     this check box's group, or <code>null</code>
  298.      *               if the check box is not part of a check box group.
  299.      * @see        java.awt.Checkbox#setCheckboxGroup
  300.      */
  301.     public CheckboxGroup getCheckboxGroup() {
  302.     return group;
  303.     }
  304.  
  305.     /**
  306.      * Sets this check box's group to be the specified check box group.
  307.      * If this check box is already in a different check box group,
  308.      * it is first taken out of that group.
  309.      * @param     g   the new check box group, or <code>null</code>
  310.      *                to remove this check box from any check box group.
  311.      * @see       java.awt.Checkbox#getCheckboxGroup
  312.      */
  313.     public void setCheckboxGroup(CheckboxGroup g) {
  314.         CheckboxGroup group = this.group;
  315.     if (group != null) {
  316.         group.setSelectedCheckbox(null);
  317.     }
  318.     /* Locking check box above could cause deadlock with
  319.      * CheckboxGroup's setSelectedCheckbox method.
  320.      */
  321.     synchronized (this) {
  322.         this.group = g;
  323.         CheckboxPeer peer = (CheckboxPeer)this.peer;
  324.         if (peer != null) {
  325.         peer.setCheckboxGroup(g);
  326.         }
  327.     }
  328.     }
  329.  
  330.     /**
  331.      * Adds the specified item listener to receive item events from
  332.      * this check box.
  333.      * If l is null, no exception is thrown and no action is performed.
  334.      *
  335.      * @param         l    the item listener
  336.      * @see           java.awt.event.ItemEvent
  337.      * @see           java.awt.event.ItemListener
  338.      * @see           java.awt.Checkbox#removeItemListener
  339.      * @since         JDK1.1
  340.      */
  341.     public synchronized void addItemListener(ItemListener l) {
  342.     if (l == null) {
  343.         return;
  344.     }
  345.         itemListener = AWTEventMulticaster.add(itemListener, l);
  346.         newEventsOnly = true;
  347.     }
  348.  
  349.     /**
  350.      * Removes the specified item listener so that the item listener
  351.      * no longer receives item events from this check box.
  352.      * If l is null, no exception is thrown and no action is performed.
  353.      *
  354.      * @param         l    the item listener
  355.      * @see           java.awt.event.ItemEvent
  356.      * @see           java.awt.event.ItemListener
  357.      * @see           java.awt.Checkbox#addItemListener
  358.      * @since         JDK1.1
  359.      */
  360.     public synchronized void removeItemListener(ItemListener l) {
  361.     if (l == null) {
  362.         return;
  363.     }
  364.         itemListener = AWTEventMulticaster.remove(itemListener, l);
  365.     }
  366.  
  367.     // REMIND: remove when filtering is done at lower level
  368.     boolean eventEnabled(AWTEvent e) {
  369.         if (e.id == ItemEvent.ITEM_STATE_CHANGED) {
  370.             if ((eventMask & AWTEvent.ITEM_EVENT_MASK) != 0 ||
  371.                 itemListener != null) {
  372.                 return true;
  373.             }
  374.             return false;
  375.         }
  376.         return super.eventEnabled(e);
  377.     }
  378.  
  379.     /**
  380.      * Processes events on this check box.
  381.      * If the event is an instance of <code>ItemEvent</code>,
  382.      * this method invokes the <code>processItemEvent</code> method.
  383.      * Otherwise, it calls its superclass's <code>processEvent</code> method.
  384.      * @param         e the event.
  385.      * @see           java.awt.event.ItemEvent
  386.      * @see           java.awt.Checkbox#processItemEvent
  387.      * @since         JDK1.1
  388.      */
  389.     protected void processEvent(AWTEvent e) {
  390.         if (e instanceof ItemEvent) {
  391.             processItemEvent((ItemEvent)e);
  392.             return;
  393.         }
  394.     super.processEvent(e);
  395.     }
  396.  
  397.     /**
  398.      * Processes item events occurring on this check box by
  399.      * dispatching them to any registered
  400.      * <code>ItemListener</code> objects.
  401.      * <p>
  402.      * This method is not called unless item events are
  403.      * enabled for this component. Item events are enabled
  404.      * when one of the following occurs:
  405.      * <p><ul>
  406.      * <li>An <code>ItemListener</code> object is registered
  407.      * via <code>addItemListener</code>.
  408.      * <li>Item events are enabled via <code>enableEvents</code>.
  409.      * </ul>
  410.      * @param       e the item event.
  411.      * @see         java.awt.event.ItemEvent
  412.      * @see         java.awt.event.ItemListener
  413.      * @see         java.awt.Checkbox#addItemListener
  414.      * @see         java.awt.Component#enableEvents
  415.      * @since       JDK1.1
  416.      */
  417.     protected void processItemEvent(ItemEvent e) {
  418.         if (itemListener != null) {
  419.             itemListener.itemStateChanged(e);
  420.         }
  421.     }
  422.  
  423.     /**
  424.      * Returns the parameter string representing the state of
  425.      * this check box. This string is useful for debugging.
  426.      * @return    the parameter string of this check box.
  427.      */
  428.     protected String paramString() {
  429.     String str = super.paramString();
  430.     String label = this.label;
  431.     if (label != null) {
  432.         str += ",label=" + label;
  433.     }
  434.     return str + ",state=" + state;
  435.     }
  436.  
  437.  
  438.     /* Serialization support.
  439.      */
  440.     
  441.     /*
  442.     * Serialized data version
  443.     * @serial
  444.     */
  445.     private int checkboxSerializedDataVersion = 1;
  446.  
  447.     /**
  448.     * Writes default serializable fields to stream.  Writes
  449.     * a list of serializable ItemListener(s) as optional data.
  450.     * The non-serializable ItemListner(s) are detected and
  451.     * no attempt is made to serialize them.
  452.     *
  453.     * @serialData Null terminated sequence of 0 or more pairs.
  454.     *             The pair consists of a String and Object.
  455.     *             The String indicates the type of object and
  456.     *             is one of the following :
  457.     *             itemListenerK indicating and ItemListener object.
  458.     *
  459.     * @see AWTEventMulticaster.save(ObjectOutputStream, String, EventListener)
  460.     * @see java.awt.Component.itemListenerK
  461.     */
  462.     private void writeObject(ObjectOutputStream s)
  463.       throws java.io.IOException
  464.     {
  465.       s.defaultWriteObject();
  466.  
  467.       AWTEventMulticaster.save(s, itemListenerK, itemListener);
  468.       s.writeObject(null);
  469.     }
  470.  
  471.     /*
  472.     * Read the ObjectInputStream and if it isnt null
  473.     * add a listener to receive item events fired
  474.     * by the Checkbox.
  475.     * Unrecognised keys or values will be Ignored.
  476.     * @serial
  477.     * @see removeActionListener()
  478.     * @see addActionListener()
  479.     */
  480.     private void readObject(ObjectInputStream s)
  481.       throws ClassNotFoundException, IOException
  482.     {
  483.       s.defaultReadObject();
  484.  
  485.       Object keyOrNull;
  486.       while(null != (keyOrNull = s.readObject())) {
  487.     String key = ((String)keyOrNull).intern();
  488.  
  489.     if (itemListenerK == key)
  490.       addItemListener((ItemListener)(s.readObject()));
  491.  
  492.     else // skip value for unrecognized key
  493.       s.readObject();
  494.       }
  495.     }
  496.  
  497.     /**
  498.      * Initialize JNI field and method ids
  499.      */
  500.     private static native void initIDs();
  501. }
  502.